package com.group.app.example.service.impl;

import com.group.app.example.common.support.CommonConstant;
import com.group.app.example.domain.FieldNodeModel;
import com.group.app.example.domain.FieldStationModel;
import com.group.app.example.repository.FieldNodeRepository;
import com.group.app.example.repository.FieldRepository;
import com.group.app.example.repository.FieldStationRepository;
import com.group.app.example.service.FieldService;
import com.group.app.example.util.DateUtil;
import com.group.app.example.util.Md5Util;
import com.group.app.example.vo.FieldWarehouseVo;
import com.group.app.example.vo.SearchVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.transaction.Transactional;
import java.util.*;

@Service
public class FieldServiceImpl implements FieldService {

    @Autowired
    FieldNodeRepository fieldNodeRepository;

    @Autowired
    FieldStationRepository fieldStationRepository;

    @Autowired
    FieldRepository fieldRepository;

    @Transactional()
    @Override
    public boolean saveFieldWarehouse(List<FieldWarehouseVo> fieldWarehouseVos, String user) {
        LinkedList<FieldStationModel> fieldStationList=new LinkedList<>();
        LinkedList<FieldNodeModel> fieldNodeList=new LinkedList<>();
        LinkedList<FieldWarehouseVo> updateList=new LinkedList<>();
        List<Map<String, Object>> allNode = fieldNodeRepository.getAllNode();
        HashMap<String,String> nodeData=new HashMap<>();
        HashMap<String,Integer> nodeName=new HashMap<>();
        nodeData.put("root","1");
        allNode.forEach(map->{
            nodeData.put((String)map.get("parent_link"),(String)map.get("code_link"));
            nodeName.put((String)map.get("name"),(Integer)map.get("code"));
        });

        fieldWarehouseVos.forEach(fieldWarehouseVo->{
            FieldNodeModel fieldNodeModel=new FieldNodeModel();
            String link = getLinkString(fieldWarehouseVo);
            //如果导入的层级结构在表中已存在，则直接创建节点
            if(nodeData.containsKey(link)){
                String codeLink = nodeData.get(link);
                String[] parentArray=codeLink.split(CommonConstant.LINK_SEPARATE);
                String parentCode=parentArray[parentArray.length-1];
                String id = Md5Util.md5(link + CommonConstant.LINK_SEPARATE + fieldWarehouseVo.getFieldName());
                fieldNodeModel.setId(id);
                fieldNodeModel.setCodeLink(codeLink);
                fieldNodeModel.setName(fieldWarehouseVo.getFieldName());
                fieldNodeModel.setCreateUser(user);
                fieldNodeModel.setParentCode(Integer.valueOf(parentCode));
                fieldNodeModel.setParentLink(link);
                fieldNodeModel.setCreateTime(DateUtil.getCurrentTime());
                fieldNodeModel.setUpdateTime(DateUtil.getCurrentTime());
                fieldNodeModel.setActiveDate(DateUtil.getTodayDate());
                fieldNodeModel.setIsNode(true);
                //此处用于判断 如果用户创建了一个父节点，并没有儿子节点
                //如果导入的结果里存在同一层级相同字段名，如果Station表中有，说明修改了该字段详情信息
                //否则这是一个新节点，需要创建
                if(fieldStationRepository.existsById(id)){
                    FieldStationModel fieldStationModel = new FieldStationModel();
                    fieldStationModel.setId(id);
                    fieldStationModel.setFieldName(fieldWarehouseVo.getFieldName());
                    fieldStationModel.setFieldType(fieldWarehouseVo.getFieldType());
                    fieldStationRepository.save(fieldStationModel);
                    //说明是更新，后续会剔除
                    updateList.add(fieldWarehouseVo);
                }else{
                    FieldNodeModel fieldNode = fieldNodeRepository.save(fieldNodeModel);
                }

            } else {
                String[] linkArray=link.split(CommonConstant.LINK_SEPARATE);
                //递归创建
                createNodeByRecursion(linkArray.length-1,0,fieldWarehouseVo.getFieldName(),link,nodeData,nodeName);
            }
        });
        fieldWarehouseVos.removeAll(updateList);
        fieldWarehouseVos.forEach(fieldWarehouseVo->{
            FieldStationModel fieldStationModel=new FieldStationModel();
            String link = getLinkString(fieldWarehouseVo);
            fieldStationModel.setId(Md5Util.md5(link + CommonConstant.LINK_SEPARATE + fieldWarehouseVo.getFieldName()));
            fieldStationModel.setFieldName(fieldWarehouseVo.getFieldName());
            fieldStationModel.setFieldType(fieldWarehouseVo.getFieldType());
            fieldStationList.add(fieldStationModel);
        });
        fieldStationRepository.saveAll(fieldStationList);
        return true;
    }

    @Override
    public Map<String, Object> findFieldByCondition(SearchVo searchVo) {
        int offset =(searchVo.getPage() - 1)*searchVo.getLimit();
        Map<String, Object> maps = fieldRepository.queryLabelInfo1(searchVo,searchVo.getLimit(),offset);
        return maps;
        // System.out.println(maps);
    }

    @Override
    public List<Map<String, Object>> allLabelInfoByCondition(SearchVo searchVo) {
        return fieldRepository.allLabelInfoByCondition(searchVo);
    }

    private String getLinkString(FieldWarehouseVo fieldWarehouseVo) {
        String link = "root" + CommonConstant.LINK_SEPARATE + fieldWarehouseVo.getFirst().trim();
        link = StringUtils.isEmpty(fieldWarehouseVo.getSecond()) ? link : link + CommonConstant.LINK_SEPARATE + fieldWarehouseVo.getSecond().trim();
        link = StringUtils.isEmpty(fieldWarehouseVo.getThird()) ? link : link + CommonConstant.LINK_SEPARATE + fieldWarehouseVo.getThird().trim();
        return link;
    }

    //递归创建父节点
    private String createNodeByRecursion(int index,int depth, String nodeName, String link, HashMap<String,String> nodeData, HashMap<String,Integer> name){
        depth++;
        if(index<0){
            return nodeName;
        }
        String oldNodeName=nodeName;
        if(!nodeData.containsKey(link)){
            String sub=link;
            nodeName=sub.substring(sub.lastIndexOf(CommonConstant.LINK_SEPARATE)).replace(CommonConstant.LINK_SEPARATE,"");
            sub=sub.replace(sub.substring(sub.lastIndexOf(CommonConstant.LINK_SEPARATE)),"");
            index--;
            createNodeByRecursion(index,depth,nodeName,sub,nodeData,name);
        }
        if(!name.containsKey(oldNodeName)){
            String codeLink=nodeData.get(link);
            String parentId=codeLink.contains(CommonConstant.LINK_SEPARATE)?codeLink.substring(codeLink.lastIndexOf(CommonConstant.LINK_SEPARATE)).replace(CommonConstant.LINK_SEPARATE,""):codeLink;
            FieldNodeModel fieldNodeModel=new FieldNodeModel();
            fieldNodeModel.setName(oldNodeName);
            fieldNodeModel.setParentCode(Integer.valueOf(parentId));
            fieldNodeModel.setCodeLink(nodeData.get(link));
            fieldNodeModel.setParentLink(link);
            fieldNodeModel.setId(Md5Util.md5(link+CommonConstant.LINK_SEPARATE+oldNodeName));
            fieldNodeModel.setCreateTime(DateUtil.getCurrentTime());
            fieldNodeModel.setUpdateTime(DateUtil.getCurrentTime());
            fieldNodeModel.setActiveDate(DateUtil.getTodayDate());
            if(depth==1){
                fieldNodeModel.setIsNode(true);
            }else{
                fieldNodeModel.setIsNode(false);
            }
            FieldNodeModel node = fieldNodeRepository.saveAndFlush(fieldNodeModel);
            nodeData.put(link+CommonConstant.LINK_SEPARATE+node.getName(),nodeData.get(link)+CommonConstant.LINK_SEPARATE+node.getCode());
            return link+CommonConstant.LINK_SEPARATE+oldNodeName+","+node.getCode();
        }else{
            nodeData.put(link+CommonConstant.LINK_SEPARATE+oldNodeName,nodeData.get(link)+CommonConstant.LINK_SEPARATE+name.get(oldNodeName));
            return link+CommonConstant.LINK_SEPARATE+oldNodeName+","+name.get(oldNodeName);
        }


    }
}
